/**
 * 
 */
package com.feib.soeasy.model;

import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;

/**
 * @title (#)User.java<br>
 * @description 使用者資料<br>
 * @author Jimmy Liu<br>
 * @version 1.0.0 2010/11/25
 * @copyright Far Eastern International Bank Copyright (c) 2010<br>
 * @20101025 create by Jimmy Liu<br>
 */
@Entity
@Table(name = "APP_USER", uniqueConstraints = { @UniqueConstraint(columnNames = { "USER_ID",
        "GROUP_PK" }) })
public class User extends AuditEntity {

    private static final long serialVersionUID = -2153357485126061383L;

    /**
     * PK in Table
     */
    private Long userPk;

    /**
     * 所屬群組
     */
    private Group group;

    /**
     * 登入帳號，unique key
     */
    private String userId;

    /**
     * 登入密碼
     */
    private String userPassWord;

    /**
     * 登入姓名
     */
    private String userName;

    /**
     * Email
     */
    private String userEmail;

    /**
     * Phone number
     */
    private String userPhone;

    /**
     * 帳號鎖定 <li>true: 是</li> <li>false: 否</li>
     */
    private Boolean locked;

    /**
     * 帳號啟用 <li>true: 啟用</li> <li>false: 停用</li>
     */
    private Boolean enabled;

    /**
     * 密碼有效日期
     */
    private Date pwdExpiredDate;

    /**
     * 最近一次登入時間/上次登入時間
     */
    private Date lastLogingDate;

    /**
     * 密碼歷史記錄
     */
    private String pwdHistory;

    /**
     * 密碼登錄錯誤次數
     */
    private Integer pwdErrorTime;
    
    /**
     * 認證碼錯誤次數
     */
    private Integer captchaErrorTime;

    /**
     * 備註
     */
    private String userMemo;

    /**
     * 使用者角色
     */
    private Set<Role> roles;

    /**
     * @return the userPk
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "USER_PK", nullable = false)
    public Long getUserPk() {
        return userPk;
    }

    /**
     * @param userPk the userPk to set
     */
    public void setUserPk(Long userPk) {
        this.userPk = userPk;
    }

    /**
     * @return the group
     */
    @ManyToOne
    @JoinColumn(name = "GROUP_PK", nullable = false)
    public Group getGroup() {
        return group;
    }

    /**
     * @param group the group to set
     */
    public void setGroup(Group group) {
        this.group = group;
    }

    /**
     * @return the userId
     */
    @Column(name = "USER_ID", nullable = false, length = 50)
    public String getUserId() {
        return userId;
    }

    /**
     * @param userId the userId to set
     */
    public void setUserId(String userId) {
        this.userId = userId;
    }

    /**
     * @return the userPassWord
     */
    @Column(name = "USER_PWD", nullable = false, length = 255)
    public String getUserPassWord() {
        return userPassWord;
    }

    /**
     * @param userPassWord the userPassWord to set
     */
    public void setUserPassWord(String userPassWord) {
        this.userPassWord = userPassWord;
    }

    /**
     * @return the userName
     */
    @Column(name = "USER_NAME", length = 20)
    public String getUserName() {
        return userName;
    }

    /**
     * @param userName the userName to set
     */
    public void setUserName(String userName) {
        this.userName = userName;
    }

    /**
     * @return the userEmail
     */
    @Column(name = "USER_EMAIL", length = 100)
    public String getUserEmail() {
        return userEmail;
    }

    /**
     * @param userEmail the userEmail to set
     */
    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    /**
     * @return the locked
     */
    @Column(name = "IS_LOCKED")
    public Boolean getLocked() {
        return locked;
    }

    /**
     * @param locked the locked to set
     */
    public void setLocked(Boolean locked) {
        this.locked = locked;
    }

    /**
     * @return the enabled
     */
    @Column(name = "IS_ENABLED")
    public Boolean getEnabled() {
        return enabled;
    }

    /**
     * @param enabled the enabled to set
     */
    public void setEnabled(Boolean enabled) {
        this.enabled = enabled;
    }

    /**
     * @return the pwdExpiredDate
     */
    @Column(name = "PWD_EXPIRED_DATE")
    public Date getPwdExpiredDate() {
        return pwdExpiredDate;
    }

    /**
     * @param pwdExpiredDate the pwdExpiredDate to set
     */
    public void setPwdExpiredDate(Date pwdExpiredDate) {
        this.pwdExpiredDate = pwdExpiredDate;
    }

    /**
     * @return the lastLogingDate
     */
    @Column(name = "LAST_LOGIN_DATE")
    public Date getLastLogingDate() {
        return lastLogingDate;
    }

    /**
     * @param lastLogingDate the lastLogingDate to set
     */
    public void setLastLogingDate(Date lastLogingDate) {
        this.lastLogingDate = lastLogingDate;
    }

    /**
     * @return 傳回 pwdHistory。
     */
    @Column(name = "PWD_HISTORY", length = 255)
    public String getPwdHistory() {
        return pwdHistory;
    }

    /**
     * @param pwdHistory 要設定的 pwdHistory。
     */
    public void setPwdHistory(String pwdHistory) {
        this.pwdHistory = pwdHistory;
    }

    /**
     * @return 傳回 pwdErrorTime。
     */
    @Column(name = "PWD_ERROR_TIME")
    public Integer getPwdErrorTime() {
        return pwdErrorTime;
    }

    /**
     * @param pwdErrorTime 要設定的 pwdErrorTime。
     */
    public void setPwdErrorTime(Integer pwdErrorTime) {
        this.pwdErrorTime = pwdErrorTime;
    }

    
    /**
     * @return the captchaErrorTime
     */
    @Column(name = "CAPTCHA_ERROR_TIME")
    public Integer getCaptchaErrorTime() {
        return captchaErrorTime;
    }

    
    /**
     * @param captchaErrorTime the captchaErrorTime to set
     */
    public void setCaptchaErrorTime(Integer captchaErrorTime) {
        this.captchaErrorTime = captchaErrorTime;
    }

    /**
     * @return the userMemo
     */
    @Column(name = "USER_MEMO", length = 255)
    public String getUserMemo() {
        return userMemo;
    }

    /**
     * @param userMemo the userMemo to set
     */
    public void setUserMemo(String userMemo) {
        this.userMemo = userMemo;
    }

    @Column(name = "USER_PHONE", length = 20)
    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public void addRole(Role e)
    {
        if (null == this.getRoles()) this.roles = new HashSet<Role>();
        this.roles.add(e);
    }
    
    /**
     * @return the roles
     */
    @ManyToMany(cascade = { CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY)
    @JoinTable(name = "USER_ROLE", joinColumns = @JoinColumn(name = "USER_PK"), inverseJoinColumns = @JoinColumn(name = "ROLE_PK"))
    public Set<Role> getRoles() {
        return roles;
    }

    /**
     * @param roles the roles to set
     */
    public void setRoles(Set<Role> roles) {
        this.roles = roles;
    }

    @Override
    public String toString() {
        return new ToStringBuilder(this).append("userPk", userPk).append("userId",
                        userId).append("userPassWord", userPassWord).append("userName",
                                                        userName).append("userEmail",
                                                                        userEmail).append("locked",
                                                                                        locked).append("enabled",
                                                                                                        enabled).append("pwdExpiredDate",
                                                                                                                        pwdExpiredDate).append("pwdHistory",
                                                                                                                                        pwdHistory).append("pwdErrorTime",
                                                                                                                                                        pwdErrorTime).append("lastLogingDate",
                                                                                                                                                                        lastLogingDate).append("userMemo",
                                                                                                                                                                                        userMemo).toString();
    }

    @Override
    public boolean equals(final Object other) {
        if (this == other)
            return true;
        if (!(other instanceof User))
            return false;
        User castOther = (User) other;
        return new EqualsBuilder().append(userPk, castOther.userPk).isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(userPk).toHashCode();
    }
}
